package org.jetlinks.community.mstn.web;


import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryOperation;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.authorization.Authentication;
import org.hswebframework.web.authorization.annotation.*;
import org.hswebframework.web.authorization.exception.UnAuthorizedException;
import org.hswebframework.web.crud.query.QueryHelper;
import org.hswebframework.web.system.authorization.api.entity.DimensionUserEntity;
import org.hswebframework.web.system.authorization.api.entity.UserEntity;
import org.hswebframework.web.system.authorization.api.service.reactive.ReactiveUserService;
import org.jetlinks.community.auth.entity.RoleEntity;
import org.jetlinks.community.auth.entity.UserDetailEntity;
import org.jetlinks.community.auth.enums.OrgType;
import org.jetlinks.community.auth.enums.RoleType;
import org.jetlinks.community.auth.service.RoleService;
import org.jetlinks.community.device.entity.request.AssetsBindRequest;
import org.jetlinks.community.device.service.AssetsService;
import org.jetlinks.community.mstn.entity.vo.UserCreateReqVO;
import org.jetlinks.community.mstn.entity.vo.UserListResVO;
import org.jetlinks.community.mstn.enums.AssetsType;
import org.jetlinks.community.mstn.service.MstnSystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@RestController
@RequestMapping("/mstn/system")
@Authorize
@Resource(id = "mstn-system", name = "平台设置", group = "mstn")
@Tag(name = "平台设置")
@AllArgsConstructor
public class MstnSystemController {

    private final RoleService roleService;

    private final AssetsService assetsService;

    //https://github.com/zhou-hao/hsweb4-examples/blob/main/hsweb4-webflux-example/src/main/java/org/hswebframework/example/crud/web/TestController.java#L36
    @Autowired
    private QueryHelper queryHelper;

    private final MstnSystemService systemService;

    private final ReactiveUserService userService;
    //新增角色
    @PostMapping("/role/{targetId}")
    @SaveAction
    @Operation(summary = "新增租户角色")
    public Mono<String> createRole(@PathVariable String targetId, @RequestBody RoleEntity roleEntity) {
        roleEntity.setRoleType(RoleType.tenantUser);
        return roleService.save(roleEntity)
                .then(Mono.fromSupplier(roleEntity::getId))
                .switchIfEmpty(Mono.error(new IllegalArgumentException("创建角色失败")))
                .flatMap(roleId ->
                {
                    AssetsBindRequest request = AssetsBindRequest.of(OrgType.project.getValue(),
                            targetId,
                            roleId,
                            AssetsType.tenantRole.getValue());
                    return assetsService.bindAssets(AssetsType.tenantRole.getValue(),Flux.just(request)).thenReturn(roleId);
                });
    }

    //修改租户角色
    @PutMapping("/role")
    @SaveAction
    @Operation(summary = "修改租户角色")
    public Mono<Boolean> updateRole( @RequestBody RoleEntity roleEntity) {
        roleEntity.setRoleType(RoleType.tenantUser);
        return roleService.updateById(roleEntity.getId(),roleEntity).map(integer -> integer > 0);
    }

    //删除租户角色
    @DeleteMapping("/role/{targetId}/{roleId}")
    @DeleteAction
    @Operation(summary = "删除租户角色")
    @Transactional
    public Mono<Boolean> deleteRole(@PathVariable String targetId, @PathVariable String roleId) {
        return assetsService.unbindAssets(AssetsType.tenantRole.getValue(),Flux.just(AssetsBindRequest.of(OrgType.project.getValue(),
                targetId,
                roleId,
                AssetsType.tenantRole.getValue())))
                .then(Mono.defer(() -> roleService.deleteById(roleId)))
                .map(integer -> integer > 0);
    }




    //查询用户列表
    @PostMapping("/user/_query")
    @QueryAction
    @QueryOperation(summary = "查询用户列表")
    public Mono<PagerResult<UserListResVO>> queryUserList(@RequestBody Mono<QueryParamEntity> param) {
        return Authentication
                .currentReactive()
                .zipWith(param)
                .switchIfEmpty(Mono.error(UnAuthorizedException::new))
                .flatMap(tp2 -> {
                    QueryParamEntity queryParamEntity = tp2.getT2();
                    //权限类型为role
                    Term roleTerm = new Term();
                    roleTerm.setValue("role");
                    roleTerm.setColumn("j_0.dimensionTypeId");
                    queryParamEntity.getTerms().add(roleTerm);

                    //角色类型为  tenant和tenantUser
                    Term roleTypeTerm = new Term();
                    roleTypeTerm.setValue("system");
                    roleTypeTerm.setColumn("j_1.roleType");
                    roleTypeTerm.setTermType("not");
                    queryParamEntity.getTerms().add(roleTypeTerm);

//                    //角色状态可用
//                    Term roleStateTerm = new Term();
//                    roleStateTerm.setValue("enabled");
//                    roleStateTerm.setColumn("j_1.state");
//                    queryParamEntity.getTerms().add(roleStateTerm);

                    //用户状态可用
//                    Term userStateTerm = new Term();
//                    userStateTerm.setValue("1");
//                    userStateTerm.setColumn("status");
//                    queryParamEntity.getTerms().add(userStateTerm);

                    return queryHelper.select(UserListResVO.class)
//                    .all(UserDetailEntity.class, SentinelUserListResVO::setDetail)
                            .all(RoleEntity.class, UserListResVO::setRoleInfo)
                            .all(UserDetailEntity.class, UserListResVO::setUserDetail)
                            .all(UserEntity.class)
                            .from(UserEntity.class)
                            .leftJoin(DimensionUserEntity.class, join -> join.is(DimensionUserEntity::getUserId,UserEntity::getId))
                            .leftJoin(RoleEntity.class, join -> join.is(RoleEntity::getId,DimensionUserEntity::getDimensionId))
                            .leftJoin(UserDetailEntity.class, join -> join.is(UserDetailEntity::getId,UserEntity::getId))
                            .where(queryParamEntity)
                            .fetchPaged();
                });
    }


    //创建一个用户，类型为user。并绑定到租户上。
    @PostMapping("/user/_create")
    @SaveAction
    @Operation(summary = "创建用户")
    @Transactional
    public Mono<String> createUser(@RequestBody Mono<UserCreateReqVO> userCreateReqVO) {
        return Authentication
                .currentReactive()
                .zipWith(userCreateReqVO)
                .switchIfEmpty(Mono.error(UnAuthorizedException::new))
                .flatMap(tp2 -> systemService.createUser(tp2.getT2(), (String) (tp2.getT1().getAttribute("tenantId").get())));
    }

    @PutMapping("/user/_update")
    @SaveAction
    @Operation(summary = "修改用户")
    @Transactional
    public Mono<String> updateUser(@RequestBody Mono<UserCreateReqVO> userCreateReqVO) {
        return Authentication
            .currentReactive()
            .zipWith(userCreateReqVO)
            .switchIfEmpty(Mono.error(UnAuthorizedException::new))
            .flatMap(tp2 -> systemService.createUser(tp2.getT2(), (String) (tp2.getT1().getAttribute("tenantId").get())));
    }

    @PostMapping("/user/_detail/{userId}")
    @QueryAction
    @Operation(summary = "用户详情")
    public Mono<UserCreateReqVO> createUser(@PathVariable String userId) {
        return systemService.getUserDetail(userId);
    }

    @DeleteMapping("/user/_del/{userId}")
    @DeleteAction
    @Operation(summary = "删除用户")
    public Mono<Boolean> delUser(@PathVariable String userId) {
        return userService.deleteUser(userId);
    }



}
